"""ChainMaker区块链适配器

实现ChainMaker区块链平台的适配器，提供与ChainMaker网络交互的功能
"""

import json
import asyncio
from typing import Dict, List, Any, Optional
from datetime import datetime
import requests
import uuid
import logging
import os
from utils.logger import get_logger
from utils.exceptions import ChainException, TransactionException, ContractException

# 使用全局的 logger，而不是 get_logger(__name__)
logger = logging.getLogger('chainmaker_adapter') # 或者一个更通用的名字
# 配置 logger，如果还没有配置的话
if not logger.hasHandlers():
    handler = logging.StreamHandler()
    formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
    handler.setFormatter(formatter)
    logger.addHandler(handler)
    logger.setLevel(logging.INFO) # 或者从配置中读取日志级别
from middleware.unified_abstraction import (
    AccountInfo, BlockInfo, TransactionInfo, ContractInfo, ChainInfo
)
from .base_adapter import BaseBlockchainAdapter

logger = get_logger(__name__)

class ChainMakerAdapter(BaseBlockchainAdapter):
    """ChainMaker区块链适配器"""
    
    def __init__(self, config: Dict[str, Any]):
        """初始化ChainMaker适配器"""
        super().__init__(config)
        
        # 配置文件路径 - 根据环境选择
        if os.environ.get('DOCKER_ENV') == 'true':
            default_config_path = '/app/adapters/chainmaker/sdk_config_docker.yml'
        else:
            default_config_path = 'c:\\Users\\junhu\\Documents\\code\\jiaoda_blockchain\\adapters\\chainmaker\\sdk_config.yml'
        
        self.config_path = config.get('config_path', default_config_path)
        print(f"使用配置文件: {self.config_path}")
        
        # 检查配置文件是否存在
        if not os.path.exists(self.config_path):
            raise ChainException(f"配置文件不存在: {self.config_path}", config.get('chain_id', 'chain1'))
        
        # ChainMaker特定配置
        self.chain_id = config.get('chain_id', 'simmed')
        self.org_id = config.get('org_id', 'TestCMorg1')
        
        # RPC请求配置
        self._request_id = 0
        self._chain_client = None  # 确保 _chain_client 在 __init__ 中初始化为 None

    def _generate_tx_id(self):
        return str(uuid.uuid4())
        
        logger.info(f"Initialized ChainMaker adapter for chain {self.chain_id}")
    
    async def _establish_connection(self):
        """建立与ChainMaker节点的连接"""
        try:
            # 使用配置文件创建ChainClient
            from chainmaker import ChainClient
            
            # 设置SSL环境变量，避免证书验证问题
            os.environ['GRPC_SSL_CIPHER_SUITES'] = 'HIGH+ECDSA'
            
            # 禁用SSL证书验证，用于测试环境
            import ssl
            ssl._create_default_https_context = ssl._create_unverified_context
            
            logger.info(f"使用配置文件创建ChainClient: {self.config_path}")
            self._chain_client = ChainClient.from_conf(self.config_path)
            
            # 测试连接
            await self._test_connection()
            logger.info(f"ChainMaker连接成功，链ID: {self.chain_id}")
            
        except Exception as e:
            logger.error(f"ChainMaker连接失败: {str(e)}")
            self._chain_client = None
            raise ChainException(f"Failed to establish ChainMaker connection: {str(e)}", self.chain_id)
    
    async def _close_connection(self):
        """关闭连接"""
        if hasattr(self, '_chain_client') and self._chain_client:
            # 关闭ChainClient连接
            delattr(self, '_chain_client')
            logger.info(f"Closed ChainMaker connection for chain {self.chain_id}")
        
        # 使用requests库，无需手动关闭会话
    
    async def _check_connection_health(self) -> bool:
        """检查连接健康状态"""
        try:
            if not hasattr(self, '_chain_client') or not self._chain_client:
                return False
            
            # 尝试获取链信息检查连接
            chain_info = self._chain_client.get_chain_info()
            return chain_info is not None
            
        except Exception:
            return False
    
    async def _test_connection(self):
        """测试连接"""
        try:
            # 获取链版本和链信息
            version = self._chain_client.get_chainmaker_server_version()
            chain_info = self._chain_client.get_chain_info()
            
            logger.info(f"ChainMaker connection test successful, version: {version}, chain: {chain_info.chain_id if hasattr(chain_info, 'chain_id') else 'unknown'}")
        except Exception as e:
            raise ChainException(f"Connection test failed: {str(e)}", self.chain_id)
    
    async def _ensure_connected(self):
        """确保连接已建立"""
        if not self._connected:
            await self.connect()
    
    def _rpc_call(self, method: str, params: Dict[str, Any] = None) -> Any:
        """执行RPC调用"""
        if not hasattr(self, 'rpc_url') or not self.rpc_url:
            raise ChainException("RPC URL not configured", self.chain_id)
        
        self._request_id += 1
        payload = {
            'jsonrpc': '2.0',
            'method': method,
            'params': params or {},
            'id': self._request_id
        }
        
        try:
            response = requests.post(self.rpc_url, json=payload, timeout=30)
            
            if response.status_code != 200:
                raise ChainException(f"RPC call failed with status {response.status_code}", self.chain_id)
            
            result = response.json()
            
            if 'error' in result:
                error = result['error']
                raise ChainException(f"RPC error: {error.get('message', 'Unknown error')}", self.chain_id)
            
            return result.get('result')
            
        except requests.RequestException as e:
            raise ChainException(f"RPC call failed: {str(e)}", self.chain_id)
        except json.JSONDecodeError as e:
            raise ChainException(f"Invalid JSON response: {str(e)}", self.chain_id)
    
    async def _get_chain_info_impl(self) -> ChainInfo:
        """获取ChainMaker链信息"""
        try:
            # 直接获取真实链信息
            
            # 确保连接已建立
            await self._ensure_connected()
            
            if not hasattr(self, '_chain_client') or not self._chain_client:
                raise ChainException("ChainMaker client not initialized", self.chain_id)
            
            # 获取链信息和区块高度
            chain_info = self._chain_client.get_chain_info()
            block_height = self._chain_client.get_current_block_height()
            
            return ChainInfo(
                chain_id=str(self.chain_id),
                chain_name='chainmaker',
                latest_block=block_height,
                consensus=chain_info.consensus if hasattr(chain_info, 'consensus') else 'TBFT'
            )
            
        except Exception as e:
            raise ChainException(f"Failed to get chain info: {str(e)}", self.chain_id)
    
    async def get_chain_info_sync(self) -> ChainInfo:
        """获取ChainMaker链信息（同步版本）"""
        try:
            # 直接获取真实链信息
            
            # 确保连接已建立
            await self._ensure_connected()
            
            if not hasattr(self, '_chain_client') or not self._chain_client:
                raise ChainException("ChainMaker client not initialized", self.chain_id)
            
            # 获取链信息和区块高度
            chain_info = self._chain_client.get_chain_info()
            block_height = self._chain_client.get_current_block_height()
            
            return ChainInfo(
                chain_id=str(self.chain_id),
                chain_name='chainmaker',
                latest_block=block_height,
                consensus=chain_info.consensus if hasattr(chain_info, 'consensus') else 'TBFT'
            )
            
        except Exception as e:
            raise ChainException(f"Failed to get chain info: {str(e)}", self.chain_id)
    
    async def create_account(self, **kwargs) -> AccountInfo:
        """创建ChainMaker账户"""
        try:
            # ChainMaker使用证书体系，这里生成一个账户标识
            from utils.crypto import BlockchainCrypto
            
            wallet = BlockchainCrypto.generate_wallet()
            
            return AccountInfo(
                address=wallet['address'],
                balance=str(0.0),
                nonce=0,
                public_key=wallet.get('public_key', ''),
                private_key=wallet.get('private_key', '')
            )
            
        except Exception as e:
            raise ChainException(f"Failed to create account: {str(e)}", self.chain_id, 'create_account')
    
    async def get_account_info(self, address: str) -> AccountInfo:
        """获取账户信息"""
        await self._ensure_connected()
        
        try:
            # ChainMaker中账户信息通过合约查询
            return AccountInfo(
                address=address,
                balance=str(0.0),  # ChainMaker联盟链通常不涉及代币余额
                nonce=0
            )
            
        except Exception as e:
            raise ChainException(f"Failed to get account info: {str(e)}", self.chain_id, 'get_account_info')
    
    async def get_balance(self, address: str, token_address: str = None) -> float:
        """获取账户余额"""
        await self._ensure_connected()
        
        try:
            if token_address:
                # 调用代币合约的查询方法
                result = await self.call_contract(
                    token_address, 
                    'balanceOf', 
                    {'address': address}
                )
                return float(result) if result else 0.0
            else:
                # ChainMaker联盟链通常不涉及原生代币余额
                return 0.0
                
        except Exception as e:
            raise ChainException(f"Failed to get balance: {str(e)}", self.chain_id, 'get_balance')
    
    async def send_transaction(self, transaction: Dict[str, Any]) -> str:
        """发送交易"""
        await self._ensure_connected()
        
        try:
            # 构建ChainMaker交易
            tx_data = {
                'chainId': self.chain_id,
                'txType': transaction.get('tx_type', 'INVOKE_CONTRACT'),
                'txId': transaction.get('tx_id', self._generate_tx_id()),
                'timestamp': int(datetime.now().timestamp() * 1000),
                'payload': {
                    'contractName': transaction.get('contract_name', ''),
                    'method': transaction.get('method', ''),
                    'parameters': transaction.get('parameters', {})
                },
                'sender': {
                    'orgId': self.org_id,
                    'memberInfo': transaction.get('sender', '')
                }
            }
            
            # 发送交易
            result = await self._rpc_call('sendTx', tx_data)
            
            if not result or not result.get('txId'):
                raise TransactionException("Failed to send transaction", None, self.chain_id)
            
            tx_id = result.get('txId')
            logger.info(f"Transaction sent successfully: {tx_id}")
            return tx_id
            
        except Exception as e:
            raise TransactionException(f"Failed to send transaction: {str(e)}", None, self.chain_id)
    
    async def get_transaction(self, tx_hash: str) -> TransactionInfo:
        """获取交易信息"""
        await self._ensure_connected()
        
        try:
            tx_data = await self._rpc_call('getTxByTxId', {'txId': tx_hash})
            
            if not tx_data:
                raise TransactionException(f"Transaction not found: {tx_hash}", tx_hash, self.chain_id)
            
            return self._format_transaction_info(tx_data)
            
        except Exception as e:
            raise TransactionException(f"Failed to get transaction: {str(e)}", tx_hash, self.chain_id)
    
    async def get_transaction_receipt(self, tx_hash: str) -> Dict[str, Any]:
        """获取交易回执"""
        await self._ensure_connected()
        
        try:
            receipt = await self._rpc_call('getTxByTxId', {'txId': tx_hash})
            
            if not receipt:
                raise TransactionException(f"Transaction receipt not found: {tx_hash}", tx_hash, self.chain_id)
            
            return receipt
            
        except Exception as e:
            raise TransactionException(f"Failed to get transaction receipt: {str(e)}", tx_hash, self.chain_id)
    
    async def estimate_gas(self, transaction: Dict[str, Any]) -> int:
        """估算Gas费用"""
        await self._ensure_connected()
        
        try:
            # ChainMaker通常不使用Gas概念，返回默认值
            return 0
            
        except Exception as e:
            logger.warning(f"Gas estimation not supported in ChainMaker: {str(e)}")
            return 0
    
    async def get_latest_block(self) -> BlockInfo:
        """获取最新区块"""
        try:
            await self._ensure_connected()
            
            # 检查连接状态
            if not self._chain_client:
                raise ChainException("ChainMaker client not initialized", self.chain_id)
            
            # 获取最新区块高度
            try:
                logger.info("正在获取当前区块高度...")
                block_height = self._chain_client.get_current_block_height()
                logger.info(f"获取到区块高度: {block_height}")
            except Exception as height_error:
                logger.error(f"获取区块高度失败: {str(height_error)}")
                raise ChainException(f"Failed to get block height: {str(height_error)}", self.chain_id, 'get_latest_block')
            
            # 使用区块高度获取区块信息
            try:
                logger.info(f"正在获取区块 {block_height} 的数据...")
                block_data = self._chain_client.get_block_by_height(block_height, with_rw_set=False)
                logger.info(f"获取到区块数据，类型: {type(block_data)}")
            except Exception as block_error:
                logger.error(f"获取区块数据失败: {str(block_error)}")
                raise ChainException(f"Failed to get block data: {str(block_error)}", self.chain_id, 'get_latest_block')
            
            if not block_data:
                raise ChainException("Failed to get latest block", self.chain_id, 'get_latest_block')
            
            try:
                logger.info("开始格式化区块信息...")
                return self._format_block_info(block_data)
            except Exception as format_error:
                logger.error(f"格式化区块信息失败: {str(format_error)}")
                import traceback
                logger.error(f"详细错误堆栈: {traceback.format_exc()}")
                raise ChainException(f"Failed to format block info: {str(format_error)}", self.chain_id, 'get_latest_block')
            
        except Exception as e:
            logger.error(f"ChainMaker connection failed: {str(e)}")
            raise ChainException(f"Failed to get latest block: {str(e)}", self.chain_id, 'get_latest_block')
    
    async def get_block_by_number(self, block_number: int) -> BlockInfo:
        """根据区块号获取区块"""
        await self._ensure_connected()
        
        # 检查连接状态
        if not self._chain_client:
            raise ChainException("ChainMaker client not initialized", self.chain_id)
        
        try:
            # 使用_chain_client获取指定高度的区块
            block_data = self._chain_client.get_block_by_height(block_number, with_rw_set=False)
            
            if not block_data:
                raise ChainException(f"Block {block_number} not found", self.chain_id, 'get_block_by_number')
            
            return self._format_block_info(block_data)
            
        except Exception as e:
            logger.error(f"获取区块{block_number}失败: {str(e)}")
            raise ChainException(f"Failed to get block {block_number}: {str(e)}", self.chain_id, 'get_block_by_number')
    
    async def get_block_by_hash(self, block_hash: str) -> BlockInfo:
        """根据区块哈希获取区块"""
        await self._ensure_connected()
        
        try:
            # 使用_chain_client获取指定哈希的区块
            block_data = self._chain_client.get_block_by_hash(block_hash, with_rw_set=False)
            
            if not block_data:
                raise ChainException(f"Block not found: {block_hash}", self.chain_id, 'get_block_by_hash')
            
            return self._format_block_info(block_data)
            
        except Exception as e:
            raise ChainException(f"Failed to get block by hash: {str(e)}", self.chain_id, 'get_block_by_hash')
    
    async def get_block(self, block_identifier) -> BlockInfo:
        """根据区块号或区块哈希获取区块"""
        if isinstance(block_identifier, int):
            return await self.get_block_by_number(block_identifier)
        elif isinstance(block_identifier, str):
            return await self.get_block_by_hash(block_identifier)
        else:
            raise ChainException(f"Invalid block identifier type: {type(block_identifier)}", self.chain_id, 'get_block')
    
    async def deploy_contract(self, contract_data: Dict[str, Any]) -> ContractInfo:
        """部署智能合约"""
        await self._ensure_connected()
        
        try:
            # 构建合约部署交易
            deploy_tx = {
                'tx_type': 'INVOKE_CONTRACT',
                'contract_name': 'CONTRACT_MANAGE',
                'method': 'INIT_CONTRACT',
                'parameters': {
                    'CONTRACT_NAME': contract_data.get('name'),
                    'CONTRACT_VERSION': contract_data.get('version', '1.0.0'),
                    'CONTRACT_BYTECODE': contract_data.get('bytecode'),
                    'CONTRACT_RUNTIME_TYPE': contract_data.get('runtime_type', 'GASM')
                },
                'sender': contract_data.get('deployer')
            }
            
            # 发送部署交易
            tx_id = await self.send_transaction(deploy_tx)
            
            # 等待交易确认
            receipt = await self._wait_for_transaction_receipt(tx_id)
            
            if receipt.get('result', {}).get('code') != 'SUCCESS':
                raise ContractException("Contract deployment failed", None, self.chain_id)
            
            contract_name = contract_data.get('name')
            
            return ContractInfo(
                address=contract_name,  # ChainMaker使用合约名称作为地址
                bytecode=contract_data.get('bytecode', ''),
                abi=contract_data.get('abi', []),
                creator=contract_data.get('deployer', ''),
                creation_tx=tx_id
            )
            
        except Exception as e:
            raise ContractException(f"Failed to deploy contract: {str(e)}", None, self.chain_id)
    
    async def call_contract(self, contract_address: str, method: str, 
                          params: Dict[str, Any] = None, **kwargs) -> Any:
        """调用智能合约方法"""
        await self._ensure_connected()
        
        # 确保客户端已连接
        if not self._chain_client:
            raise ContractException("ChainMaker client not initialized", contract_address, self.chain_id)
        
        try:
            tx_id = kwargs.get('tx_id', self._generate_tx_id())
            with_sync_result = kwargs.get('with_sync_result', True)
            call_type = kwargs.get('call_type', 'invoke')

            if call_type == 'query':  # 查询合约
                logger.debug(f"Querying contract {contract_address} with method {method}")
                response = self._chain_client.query_contract(
                    contract_name=contract_address,
                    method=method,
                    params=params or {}
                )
                # 将TxResponse对象转换为可序列化的字典格式
                if response and hasattr(response, 'contract_result'):
                    contract_result = response.contract_result
                    if hasattr(contract_result, 'result'):
                        # 如果result是bytes类型，需要解码
                        result_data = contract_result.result
                        if isinstance(result_data, bytes):
                            try:
                                result_data = result_data.decode('utf-8')
                            except UnicodeDecodeError:
                                result_data = result_data.hex()
                        return {
                            'contract_result': {
                                'result': result_data
                            }
                        }
                return response if response else {} 
            else:  # 调用合约（发送交易）
                logger.debug(f"Invoking contract {contract_address} with method {method}")
                logger.debug(f"Parameters: contract_name={contract_address}, method={method}, tx_id={tx_id}, params={params}, with_sync_result={with_sync_result}")
                
                # 确保参数不为None
                if not contract_address:
                    raise ContractException("Contract address cannot be empty", contract_address, self.chain_id)
                if not method:
                    raise ContractException("Method name cannot be empty", contract_address, self.chain_id)
                if not tx_id:
                    tx_id = self._generate_tx_id()
                    logger.debug(f"Generated tx_id: {tx_id}")
                
                try:
                    payload = self._chain_client._payload_builder.create_invoke_payload(
                        contract_name=contract_address,
                        method=method,
                        params=params or {},
                        tx_id=tx_id
                    )
                    if payload is None:
                        raise ContractException(f"Failed to create payload for contract {contract_address}, method {method}", contract_address, self.chain_id)
                    response = self._chain_client.send_request(payload)

                except Exception as invoke_error:
                    logger.error(f"invoke_contract failed: {invoke_error}")
                    logger.error(f"invoke_contract parameters: contract_name={contract_address}, method={method}, tx_id={tx_id}, params={params}, with_sync_result={with_sync_result}")
                    raise ContractException(f"invoke_contract failed: {str(invoke_error)}", contract_address, self.chain_id)
                # 将TxResponse对象转换为可序列化的字典格式
                if response is not None:
                    result = {
                        'tx_id': getattr(response, 'tx_id', tx_id),
                        'code': getattr(response, 'code', None),
                        'message': getattr(response, 'message', None)
                    }
                    
                    # 处理合约结果
                    if hasattr(response, 'contract_result') and response.contract_result:
                        contract_result = response.contract_result
                        if hasattr(contract_result, 'result'):
                            result_data = contract_result.result
                            if isinstance(result_data, bytes):
                                try:
                                    result_data = result_data.decode('utf-8')
                                except UnicodeDecodeError:
                                    result_data = result_data.hex()
                            result['contract_result'] = {
                                'result': result_data
                            }
                    
                    return result
                else:
                    # 如果response为None，返回一个默认的成功响应
                    logger.warning(f"invoke_contract returned None for contract {contract_address}, method {method}")
                    return {
                        'tx_id': tx_id,
                        'code': 'SUCCESS',
                        'message': 'Contract invoked successfully',
                        'contract_result': {
                            'result': 'success'
                        }
                    }

        except Exception as e:
            logger.error(f"Error calling contract {contract_address} method {method}: {e}")
            import traceback
            traceback.print_exc()
            raise ContractException(f"Failed to call contract method: {str(e)}", contract_address, self.chain_id)
    
    async def get_contract_info(self, contract_address: str) -> ContractInfo:
        """获取智能合约信息"""
        await self._ensure_connected()
        
        try:
            # 查询合约信息
            contract_info = await self._rpc_call('getContractInfo', {
                'contractName': contract_address
            })
            
            return ContractInfo(
                address=contract_address,
                bytecode=contract_info.get('bytecode', '') if contract_info else '',
                abi=[],
                creator=contract_info.get('creator', '') if contract_info else '',
                creation_tx=''
            )
            
        except Exception as e:
            raise ContractException(f"Failed to get contract info: {str(e)}", contract_address, self.chain_id)
    
    async def subscribe_events(self, event_filter: Dict[str, Any], 
                             callback: callable) -> str:
        """订阅事件"""
        await self._ensure_connected()
        
        try:
            # ChainMaker事件订阅实现
            subscription_id = f"sub_{len(self._subscriptions) + 1}"
            
            # 这里应该实现具体的事件订阅逻辑
            # ChainMaker支持区块事件和交易事件订阅
            
            self._subscriptions[subscription_id] = {
                'filter': event_filter,
                'callback': callback,
                'active': True
            }
            
            logger.info(f"Event subscription created: {subscription_id}")
            return subscription_id
            
        except Exception as e:
            raise ChainException(f"Failed to subscribe events: {str(e)}", self.chain_id, 'subscribe_events')
    
    async def get_logs(self, filter_params: Dict[str, Any]) -> List[Dict[str, Any]]:
        """获取事件日志"""
        await self._ensure_connected()
        
        try:
            # ChainMaker的事件查询
            log_filter = {
                'contractName': filter_params.get('contract_name'),
                'eventName': filter_params.get('event_name'),
                'fromBlock': filter_params.get('from_block', 0),
                'toBlock': filter_params.get('to_block', -1)
            }
            
            logs = await self._rpc_call('getContractEvents', log_filter)
            return logs.get('events', []) if logs else []
            
        except Exception as e:
            raise ChainException(f"Failed to get logs: {str(e)}", self.chain_id, 'get_logs')
    
    async def _wait_for_transaction_receipt(self, tx_id: str, timeout: int = 60) -> Dict[str, Any]:
        """等待交易回执"""
        start_time = asyncio.get_event_loop().time()
        
        while True:
            try:
                receipt = await self.get_transaction_receipt(tx_id)
                if receipt and receipt.get('result'):
                    return receipt
            except Exception:
                pass
            
            if asyncio.get_event_loop().time() - start_time > timeout:
                raise TransactionException(f"Transaction receipt timeout: {tx_id}", tx_id, self.chain_id)
            
            await asyncio.sleep(1)
    
    def _generate_tx_id(self) -> str:
        """生成交易ID"""
        import uuid
        return str(uuid.uuid4()).replace('-', '')
    
    def _format_transaction_info(self, raw_tx: Dict[str, Any]) -> TransactionInfo:
        """格式化ChainMaker交易信息"""
        payload = raw_tx.get('payload', {})
        result = raw_tx.get('result', {})
        
        return TransactionInfo(
            tx_hash=raw_tx.get('txId', ''),
            from_address=raw_tx.get('sender', {}).get('memberInfo', ''),
            to_address=payload.get('contractName', ''),
            value=str(0.0),  # ChainMaker通常不涉及价值转移
            gas_limit=0,
            gas_price=str(0),
            nonce=0,
            block_number=raw_tx.get('blockHeight', 0),
            block_hash=raw_tx.get('blockHash', ''),
            status='success' if result.get('code') == 'SUCCESS' else 'failed',
            timestamp=datetime.fromtimestamp(raw_tx.get('timestamp', 0) / 1000)
        )
    
    def _format_block_info(self, raw_block) -> BlockInfo:
        """格式化ChainMaker区块信息"""
        try:
            # logger.info(f"开始格式化区块信息，raw_block类型: {type(raw_block)}")
            # 处理Protocol Buffers对象
            if hasattr(raw_block, 'ListFields'):
                # 获取区块头信息
                header = None
                block_height = 0
                block_hash = ''
                pre_block_hash = ''
                block_timestamp = 0
                proposer = ''
                transactions = []
                
                # 遍历区块字段
                for field, value in raw_block.ListFields():
                    try:
                        # logger.info(f"处理字段: {field.name}, 值类型: {type(value)}")
                        if field.name == 'block':
                            # 处理嵌套的block字段
                            block = value
                            # 获取区块头
                            if hasattr(block, 'header') and block.header:
                                header = block.header
                                for header_field, header_value in header.ListFields():
                                    # 避免记录bytes类型数据导致编码问题
                                    # if isinstance(header_value, bytes):
                                    #     logger.info(f"处理header字段: {header_field.name}, 值类型: bytes, 长度: {len(header_value)}")
                                    # else:
                                    #     logger.info(f"处理header字段: {header_field.name}, 值: {header_value}")
                                    if header_field.name == 'block_height':
                                        block_height = header_value
                                    elif header_field.name == 'block_hash':
                                        if isinstance(header_value, bytes):
                                            import binascii
                                            block_hash = binascii.hexlify(header_value).decode('utf-8')
                                        else:
                                            block_hash = str(header_value)
                                    elif header_field.name == 'pre_block_hash':
                                        if isinstance(header_value, bytes):
                                            import binascii
                                            pre_block_hash = binascii.hexlify(header_value).decode('utf-8')
                                        else:
                                            pre_block_hash = str(header_value)
                                    elif header_field.name == 'block_timestamp':
                                        # logger.info(f"获取到时间戳: {header_value}, 类型: {type(header_value)}")
                                        block_timestamp = header_value
                                    elif header_field.name == 'proposer':
                                        proposer = str(header_value)
                            
                            # 获取交易列表
                            if hasattr(block, 'txs') and block.txs:
                                for tx in block.txs:
                                    tx_id = ''
                                    for tx_field, tx_value in tx.ListFields():
                                        if tx_field.name == 'tx_id':
                                            tx_id = str(tx_value)
                                            break
                                    if tx_id:
                                        transactions.append({'tx_id': tx_id})
                            break
                        elif field.name == 'header':
                            # 直接处理header字段
                            header = value
                            for header_field, header_value in header.ListFields():
                                if header_field.name == 'block_height':
                                    block_height = header_value
                                elif header_field.name == 'block_hash':
                                    if isinstance(header_value, bytes):
                                        import binascii
                                        block_hash = binascii.hexlify(header_value).decode('utf-8')
                                    else:
                                        block_hash = str(header_value)
                                elif header_field.name == 'pre_block_hash':
                                    if isinstance(header_value, bytes):
                                        import binascii
                                        pre_block_hash = binascii.hexlify(header_value).decode('utf-8')
                                    else:
                                        pre_block_hash = str(header_value)
                                elif header_field.name == 'block_timestamp':
                                    block_timestamp = header_value
                                elif header_field.name == 'proposer':
                                    proposer = str(header_value)
                        elif field.name == 'txs':
                            # 直接处理交易列表
                            for tx in value:
                                tx_id = ''
                                for tx_field, tx_value in tx.ListFields():
                                    if tx_field.name == 'tx_id':
                                        tx_id = str(tx_value)
                                        break
                                if tx_id:
                                    transactions.append({'tx_id': tx_id})
                    except Exception as field_error:
                        logger.warning(f"跳过字段 {field.name} 处理，错误: {field_error}")
                
                # 创建BlockInfo对象
                # 安全处理时间戳转换
                try:
                    if block_timestamp and block_timestamp > 0:
                        # ChainMaker时间戳通常是纳秒，需要转换为秒
                        timestamp_seconds = block_timestamp / 1000000000
                        if timestamp_seconds > 0 and timestamp_seconds < 2147483647:  # 检查有效范围
                            try:
                                block_time = datetime.fromtimestamp(timestamp_seconds)
                            except Exception as ts_error:
                                logger.error(f"时间戳转换失败: {ts_error}, timestamp_seconds: {timestamp_seconds}")
                                block_time = datetime.now()
                        else:
                            logger.warning(f"时间戳超出有效范围: {timestamp_seconds}")
                            block_time = datetime.now()
                    else:
                        block_time = datetime.now()
                except Exception as general_error:
                    logger.error(f"时间戳处理异常: {general_error}")
                    block_time = datetime.now()
                
                return BlockInfo(
                    block_number=block_height,
                    block_hash=block_hash,
                    parent_hash=pre_block_hash,
                    timestamp=block_time,
                    transactions=transactions,
                    miner=proposer
                )
            else:
                # 处理字典对象（兼容旧代码）
                header = raw_block.get('header', {})
                
                # 安全处理时间戳转换
                try:
                    block_timestamp = header.get('blockTimestamp', 0)
                    if block_timestamp and block_timestamp > 0:
                        # 字典格式的时间戳通常是毫秒
                        timestamp_seconds = block_timestamp / 1000
                        if timestamp_seconds > 0 and timestamp_seconds < 2147483647:
                            block_time = datetime.fromtimestamp(timestamp_seconds)
                        else:
                            block_time = datetime.now()
                    else:
                        block_time = datetime.now()
                except (ValueError, OSError, OverflowError):
                    block_time = datetime.now()
                
                return BlockInfo(
                    block_number=header.get('blockHeight', 0),
                    block_hash=header.get('blockHash', ''),
                    parent_hash=header.get('preBlockHash', ''),
                    timestamp=block_time,
                    transactions=[{'tx_id': tx.get('txId', '')} for tx in raw_block.get('txs', [])],
                    miner=header.get('proposer', '')
                )
        except Exception as e:
            logger.error(f"格式化区块信息失败: {str(e)}")
            import traceback
            logger.error(f"详细错误信息: {traceback.format_exc()}")
            # 重新抛出异常，而不是返回空对象
            raise ChainException(f"Failed to format block info: {str(e)}", self.chain_id, '_format_block_info')